home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / info-service / gopher / Unix / gopher1.12 / gopherd / index.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-12-21  |  10.2 KB  |  462 lines

  1. /********************************************************************
  2.  * $Author: lindner $
  3.  * $Revision: 1.2 $
  4.  * $Date: 1992/12/14 21:36:05 $
  5.  * $Source: /home/mudhoney/GopherSrc/release1.11/gopherd/RCS/index.c,v $
  6.  * $Status: $
  7.  *
  8.  * Paul Lindner, University of Minnesota CIS.
  9.  *
  10.  * Copyright 1991, 1992 by the Regents of the University of Minnesota
  11.  * see the file "Copyright" in the distribution for conditions of use.
  12.  *********************************************************************
  13.  * MODULE: index.c
  14.  * Routines to deal with various types of indexes.
  15.  *********************************************************************
  16.  * Revision History:
  17.  * $Log: index.c,v $
  18.  * Revision 1.2  1992/12/14  21:36:05  lindner
  19.  * Fixed problem in ShellIndexQuery, cp wasn't being incremented.
  20.  * Also added special character elimination from GrepIndexQuery
  21.  *
  22.  * Revision 1.1  1992/12/10  23:13:27  lindner
  23.  * gopher 1.1 release
  24.  *
  25.  *
  26.  *********************************************************************/
  27.  
  28. #include "gopherd.h"
  29. #include <stdio.h>
  30.  
  31. #define WAISTYPE 1
  32. #define NEXTTYPE 2
  33. #define SHLLTYPE 3
  34. #define GREPTYPE 4
  35.  
  36.  
  37. void 
  38. Do_IndexTrans(sockfd, inputline)
  39.   int sockfd;
  40.   char *inputline;
  41. {
  42.      char *IndexDirectory = NULL;
  43.      char *SearchString = NULL;
  44.      char *cp = NULL;
  45.      char *dbName = NULL;
  46.      char INDEXHost[256], INDEXPath[256];  /** Hard coded limits, ugh! **/
  47.      int  INDEXPort=0;
  48.      char logline[256];
  49.      int  Index_type=0;
  50.  
  51.      /** First siphon off the directory pathname **/
  52.      IndexDirectory = inputline;
  53.  
  54.      if (UsingHTML)
  55.       cp = strchr(inputline, '?');
  56.      else
  57.       cp = strchr(inputline, '\t');
  58.      
  59.      if (cp == NULL) {
  60.       if (UsingHTML) {
  61.            Index_type = Find_index_type(IndexDirectory);
  62.  
  63.            if (Index_type == -1) {
  64.             writestring(sockfd, "Server error....<P>\r\n");
  65.             writestring(sockfd, inputline);
  66.             writestring(sockfd, " is not a valid index<P>\r\n");
  67.             return;
  68.            }
  69.            writestring(sockfd, "<ISINDEX>\r\n");
  70.            writestring(sockfd, "This is a gopher index of ");
  71.            writestring(sockfd, inputline+1);
  72.            writestring(sockfd, ". <P>This is a ");
  73.            switch (Index_type) {
  74.            case WAISTYPE:
  75.             writestring(sockfd, "WAIS index\r\n");
  76.             break;
  77.            case NEXTTYPE:
  78.             writestring(sockfd, "NeXT Digital Librarian index\r\n");
  79.             break;
  80.            case GREPTYPE:
  81.             writestring(sockfd, "Brute force search of items in this directory\r\n");
  82.             break;
  83.            case SHLLTYPE:
  84.             writestring(sockfd, "strange gateway search\r\n");
  85.             break;
  86.            } 
  87.            writestring(sockfd, "<P>\r\n");
  88.            return;
  89.  
  90.       } else {
  91.            /** Give up it won't work..... **/
  92.            writestring(sockfd, ".\r\n");
  93.            return;
  94.       } 
  95.      }
  96.      else
  97.       *cp = '\0';
  98.  
  99.      
  100.      /** And siphon off the search string **/
  101.  
  102.      SearchString = cp +1;
  103.  
  104.      /** Just in case, get rid of anything following a tab **/
  105.  
  106.      cp = strchr(SearchString, '\t');
  107.      if (cp != NULL)
  108.       *cp = '\0';
  109.  
  110.  
  111.      Index_type = Find_index_type(IndexDirectory);
  112.  
  113.      if (DEBUG) 
  114.       printf("Index type is %d\n", Index_type);
  115.  
  116.      if (Index_type < 0) {
  117.       /**** Error condition, unknown index type... ****/
  118.       Abortoutput(sockfd, "Unknown index type");
  119.       return;
  120.      }
  121.       
  122.      if (Index_type == WAISTYPE) {
  123.       /*** The selector string has both the directory and the dbname... ***/
  124.       cp = strrchr(IndexDirectory, '/');
  125.       
  126.       if (cp == NULL)
  127.            dbName = "index";
  128.       else {
  129.            dbName= cp+1;
  130.            *cp='\0';
  131.       }
  132.      }
  133.  
  134.      if (Read_hostdata(IndexDirectory, INDEXHost, &INDEXPort, INDEXPath, dbName) <0) {
  135.       LOGGopher(sockfd, "Malformed hostdata file\n");
  136.       writestring(sockfd, "0Error on server, malformed hostdata\t\t\t1\r\n.\r\n");
  137.       return;
  138.      }
  139.      
  140.      /* Doctor up the indexdirectory path if we're not running chroot()
  141.       * we use fixfile to keep things secure....
  142.       */
  143.  
  144.      if (!dochroot) {
  145.       IndexDirectory = fixfile(IndexDirectory);
  146.       
  147.       cp = (char *) malloc(250);
  148.       strcpy(cp, Data_Dir);
  149.       strcat(cp, "/");
  150.       strcat(cp, IndexDirectory);
  151.  
  152.       IndexDirectory = cp;
  153.      }
  154.  
  155.  
  156.      /** And call the appropriate query function **/
  157.  
  158.      switch (Index_type) {
  159.  
  160.      case NEXTTYPE:
  161.       
  162.       NeXTIndexQuery(sockfd, SearchString, IndexDirectory, NULL, 
  163.              INDEXHost, INDEXPort, INDEXPath);
  164.       break;
  165.  
  166.      case WAISTYPE:
  167.       WaisIndexQuery(sockfd, IndexDirectory, SearchString, dbName, 
  168.              INDEXHost, INDEXPort, INDEXPath);
  169.       break;
  170.  
  171.      case GREPTYPE:
  172.       GrepIndexQuery(sockfd, IndexDirectory, SearchString, 
  173.              INDEXHost, INDEXPort, INDEXPath);
  174.       break;
  175.       
  176.      case SHLLTYPE:
  177.       ShellIndexQuery(sockfd, IndexDirectory, SearchString);
  178.       break;
  179.      }
  180.      
  181.      /** Log it here so we get the query in the logfile **/
  182.  
  183.      if (dbName)
  184.       sprintf(logline, "search %s/%s for %s", IndexDirectory,
  185.           dbName, SearchString);
  186.      else
  187.       sprintf(logline, "search %s for %s", IndexDirectory, SearchString);
  188.  
  189.      LOGGopher(sockfd, logline);
  190. }
  191.  
  192.  
  193.  
  194. /*
  195.  * Try to figure out what each type of object is
  196.  *
  197.  * index types are 
  198.  *   Error       == -1
  199.  *   WAIS        == 1
  200.  *   NeXT        == 2
  201.  *   ShellScript == 3
  202.  *   Grep        == 4
  203.  */
  204.  
  205. int
  206. Find_index_type(gopherpath)
  207.   char *gopherpath;
  208. {
  209.      char Teststr[512];
  210.      FILE *Testfile;
  211.  
  212.      strcpy(Teststr, gopherpath);
  213.      strcat(Teststr, "/.index/index.ixif");
  214.  
  215.      Testfile = rfopen(Teststr, "r");
  216.      if (Testfile != NULL) {
  217.       /*** Next Index ***/
  218.       fclose(Testfile);
  219.       return(NEXTTYPE);
  220.      }
  221.  
  222.  
  223.      strcpy(Teststr, gopherpath);
  224.      strcat(Teststr, ".inv");
  225.  
  226.      Testfile = rfopen(Teststr, "r");
  227.      if (Testfile != NULL) {
  228.       /*** WAIS Index ***/
  229.       fclose(Testfile);
  230.       return(WAISTYPE);
  231.      }
  232.  
  233.  
  234.      strcpy(Teststr, gopherpath);
  235.  
  236.      if (isadir(Teststr) == 1) {
  237.       return(GREPTYPE);
  238.      }
  239.      
  240.      Testfile = rfopen(Teststr, "r");
  241.      if (Testfile != NULL) {
  242.       /** Shell script? **/
  243.       if (getc(Testfile) == '#')
  244.            if (getc(Testfile) == '!') {
  245.             fclose(Testfile);
  246.             return(SHLLTYPE);
  247.            }
  248.      }
  249.  
  250.      return(-1);
  251. }
  252.      
  253.  
  254. /*
  255.  * Read in the data from a hostdata file...
  256.  * 
  257.  * Try "<dbname>.hostdata" first, fall back to "hostdata" otherwise
  258.  */
  259.  
  260. int
  261. Read_hostdata(IndexDirectory, INDEXHost, INDEXPort, INDEXPath, dbName)
  262.   char *IndexDirectory;
  263.   char *INDEXHost, *INDEXPath;
  264.   int  *INDEXPort;
  265.   char *dbName;
  266. {
  267.      FILE *Hostfile;
  268.      char hostdataName[256];
  269.  
  270.      /** Read in the proper hostdata file.... **/
  271.  
  272.      rchdir(IndexDirectory);  /** Change into the index directory **/
  273.  
  274.      sprintf(hostdataName, "%s.hostdata", dbName);  /* try idx.hostdata */
  275.      if ((Hostfile = ufopen(hostdataName, "r")) == NULL)
  276.       Hostfile = ufopen("hostdata", "r");
  277.  
  278.      if (Hostfile == NULL) {
  279.       /*** Use the current host/port as the default ***/
  280.       fclose(Hostfile);
  281.       strcpy(INDEXHost, Zehostname);
  282.       *INDEXPort = GopherPort;
  283.       strcpy(INDEXPath, Data_Dir);
  284.      } 
  285.      else {
  286.       char tempbuf[255];
  287.  
  288.       if (fgets(INDEXHost, 64, Hostfile) == NULL)
  289.            return(-1);
  290.       
  291.       ZapCRLF(INDEXHost);
  292.       
  293.       if (fgets(tempbuf, 255, Hostfile) == NULL)
  294.            return(-1);
  295.       
  296.       if ((*INDEXPort=atoi(tempbuf))==0)
  297.            return(-1);
  298.       
  299.       if (fgets(INDEXPath, 256, Hostfile) == NULL)
  300.            return(-1);
  301.       
  302.       ZapCRLF(INDEXPath);
  303.       fclose(Hostfile);
  304.      }
  305.      
  306.      return(0);
  307. }
  308.  
  309.  
  310. /*
  311.  * This is a searching function that runs grep across files
  312.  * in a single directory...
  313.  */
  314.  
  315. void
  316. GrepIndexQuery(sockfd, Indexdir, Searchstr, INDEXHost, INDEXPort, INDEXPath)
  317.   int sockfd;
  318.   char *Indexdir;
  319.   char *Searchstr;
  320.   char *INDEXHost;
  321.   int INDEXPort;
  322.   char *INDEXPath;
  323. {
  324.      FILE *moocow;
  325.      char command[512];
  326.      char inputline[512];
  327.      char *cp;
  328.      GopherObj *gs;
  329.      GopherDirObj *gd;
  330.  
  331.      gs = GSnew();
  332.      gd = GDnew(32);
  333.  
  334.      cp = Searchstr;
  335.      while (*cp != '\0') {
  336.       if (*cp == ';' ||*cp == '"' || *cp == '`')
  337.            *cp = '.';
  338.       cp++;
  339.      }
  340.  
  341.      sprintf(command, "egrep \"%s\" \"%s\"/*", Searchstr, Indexdir);
  342.      if (DEBUG) 
  343.       printf("Grep command is %s\n", command);
  344.  
  345.      moocow = popen(command, "r");
  346.      
  347.      if (moocow == NULL) {
  348.       writestring(sockfd, ".\r\n");
  349.       LOGGopher(sockfd, "Couldn't open grep command");
  350.       return;
  351.      }
  352.  
  353.      while (fgets(inputline, 512, moocow)) {
  354.       ZapCRLF(inputline);
  355.       GSsetType(gs, '0');
  356.  
  357.       cp = strstr(inputline, INDEXPath) + strlen(INDEXPath);
  358.       GSsetTitle(gs, cp);
  359.  
  360.       cp = strchr(inputline, ':');
  361.       *cp='\0';
  362.       cp =strstr(inputline, INDEXPath) + strlen(INDEXPath);
  363.       GSsetPath(gs, cp);
  364.       GSsetHost(gs, INDEXHost);
  365.       GSsetPort(gs, INDEXPort);
  366.  
  367.       GDaddGS(gd, gs);
  368.      }
  369.      if (UsingHTML)
  370.       GDtoNetHTML(gd, sockfd);
  371.      else {
  372.       GDtoNet(gd, sockfd);
  373.       writestring(sockfd, ".\r\n");
  374.      }
  375.  
  376.      pclose(moocow);
  377. }
  378.  
  379.  
  380.  
  381. /*
  382.  * This starts up a shell script that's defined to be an index gateway
  383.  * 
  384.  * The shell script should write out standard gopher directory protocol.
  385.  */
  386.  
  387. void
  388. ShellIndexQuery(sockfd, Script, Searchstring)
  389.   int sockfd;
  390.   char *Script;
  391.   char *Searchstring;
  392. {
  393.      GopherDirObj *gd;
  394.      char Command[512];
  395.      FILE  *Searchprocess;
  396.      char *cp;
  397.  
  398.      gd = GDnew(32);
  399.  
  400.      /*** Clean up the arguments, remove  ; and " and `**/
  401.      cp = Searchstring;
  402.      while (*cp != '\0') {
  403.       if (*cp == ';' ||*cp == '"' || *cp == '`')
  404.            *cp = '.';
  405.       cp++;
  406.      }
  407.       
  408.  
  409.      sprintf(Command, "\"%s\" \"%s\"", Script, Searchstring);
  410.  
  411.      Searchprocess = popen(Command, "r");
  412.  
  413.      if (Searchprocess == NULL) {
  414.       writestring(sockfd, ".\r\n");
  415.       return;
  416.      }
  417.  
  418.      GDfromNet(gd, fileno(Searchprocess), NULL);
  419.      if (UsingHTML)
  420.       GDtoNetHTML(gd, sockfd);
  421.      else {
  422.       GDtoNet(gd, sockfd);
  423.       writestring(sockfd, ".\r\n");
  424.      }
  425.  
  426.      pclose(Searchprocess);
  427.      GDdestroy(gd);
  428. }
  429.  
  430.       
  431. #ifndef WAISSEARCH
  432.  
  433. void
  434. WaisIndexQuery(sockfd, index_directory, SearchWords, new_db_name, INDEXHost, INDEXPort, INDEXPath)
  435.   int sockfd;
  436.   char *index_directory;
  437.   char *SearchWords;
  438.   char *new_db_name;
  439.   char *INDEXHost;
  440.   int  INDEXPort;
  441.   char *INDEXPath;
  442. {
  443.      Abortoutput(sockfd, "Sorry, this isn't a WAIS index...");
  444.      return;
  445. }
  446. #endif 
  447.  
  448. #ifndef NEXTSEARCH
  449. void
  450. NeXTIndexQuery(sockfd, SearchWords, ZIndexDirectory, DatabaseNm, INDEXHost, INDEXPort)
  451.   int sockfd;
  452.   char *SearchWords;
  453.   char *ZIndexDirectory;
  454.   char *DatabaseNm;  /*** Not used by the next indexer... ***/
  455.   char *INDEXHost;
  456.   int INDEXPort;
  457. {
  458.      Abortoutput(sockfd, "This isn't a NeXT... is it?");
  459.      return;
  460. }
  461. #endif
  462.